chore: make the maintainer the only approval that satisfies the review gate - #1464
Conversation
main already required one approving review, but nothing said whose. In a public repo two drive-by contributors can approve each other, and with the CI checks green that is enough to merge. A CODEOWNERS file naming me for every path plus require_code_owner_reviews closes that: the one required approval now has to be mine. The two halves only work together. require_code_owner_reviews with no CODEOWNERS matches nothing and is a silent no-op, which is why the setting and the file land in the same commit. Re-running the script also repairs a drift I found while checking the live rule: it enforces five contexts, but ci.yml has six jobs and the script has listed all six for a while. "In-repo app tests (website + blog)" was never required. The skill doc said five as well, so it is corrected to six. Claude-Session: https://claude.ai/code/session_01MYGjB4NnsBZaDktR2E4y2Q
|
Decision: a CODEOWNERS gate rather than a second required approval, and why enforce_admins stays off Two alternatives I looked at and rejected before settling on this shape. Raising Moving to a repository ruleset instead of classic branch protection. Rulesets are The tradeoff I am taking with eyes open: Follow-up: nothing applies this script automatically Worth writing down because it has bitten once already. The script is the source |
Closes #1463
Summary
mainalready required one approving review, but nothing said whose. Now thatthe repo takes outside contributions, two drive-by contributors can approve each
other's PRs, and with CI green that is enough to merge. This makes the maintainer
the only approval that satisfies the gate.
Two halves, and they only work as a pair:
.github/CODEOWNERSnames@vivek7405for every path.scripts/protect-main.shflipsrequire_code_owner_reviewstotrue.require_code_owner_reviewswith no CODEOWNERS file matches nothing and is asilent no-op, which is why both land in one commit.
enforce_adminsstaysfalse, unchanged: GitHub will not let me approve my own PR, so without theadmin bypass every solo PR would be unmergeable.
Re-running the script also repairs a drift I noticed while reading the live rule.
Protection enforces five required contexts, but
ci.ymlhas six jobs and thescript has listed all six for a while, so
In-repo app tests (website + blog)was never actually required. Applying the script fixes that as a side effect.
Applying it
The script is the source of truth but nothing runs it automatically, so the rule
does not change until someone with repo admin runs it:
I will run it after this merges, and confirm with
gh api repos/webjsdev/webjs/branches/main/protection.Definition of done
config file plus the shell script that pushes branch protection through the
API; there is no unit, browser, e2e, smoke, or Bun surface to assert against.
It is verified by reading back the live protection object after the script
runs, which is in the Applying it section above.
.claude/skills/webjs-start-work/SKILL.md, whose mergesection described the gate as five contexts and did not mention who the
approval has to come from. Both corrected. No other markdown describes branch
protection (checked with a repo-wide grep for
protect-main,branch protection,approving review,CODEOWNERS).a user reads about.
project repo governance.
or served wire changed. Nothing the blog or website serves is affected.
https://claude.ai/code/session_01MYGjB4NnsBZaDktR2E4y2Q